import { LcDocument, LcProject } from '../../../types/editor.type';
import { getDocumentPath, getTypePath } from './source-path';
import { generateDocumentCode } from '../../code-transformer/schemaToCode/fileGen';
import * as crypto from 'crypto';
import { ITypeEntity } from '@/types/modules/superType/types/type/superType.type';
import { getTypeFileCode } from '../adapters/pipe/getFileCode';

/**
 * 项目配置文件中允许的字段
 * 与 getProjectFile 函数保持一致
 */
export const PROJECT_CONFIG_FIELDS: (keyof LcProject)[] = [
  'type',
  'title',
  'description',
  'frames',
  'clients',
  'width',
  'height',
  'packages',
  'envInfo',
  'appConfig',
  'theme',
  'themes',
  'assets'
];

/**
 * 私有方法：生成哈希
 */
export function calculateHash(content: string): string {
  const normalizedContent = content.replace(/\r\n/g, '\n');
  return crypto
    .createHash('sha256')
    .update(normalizedContent, 'utf8')
    .digest('hex');
}

/**
 * 计算文档的TSX和CSS哈希值
 * @param doc 文档对象
 * @returns 返回tsxHash、cssHash、代码内容和提取的cssContent
 */
export async function calculateDocumentHashes(doc: LcDocument): Promise<{
  path: string;
  tsxHash: string | null;
  cssHash: string | null;
  cssPath: string | null;
  cleanedSchema: object;
  tsxContent: string; // 🆕 返回生成的 TSX 代码
  cssContent: string | null; // 🆕 返回 CSS 内容
}> {
  let path = getDocumentPath(doc).replace('.doc', '.tsx');
  let tsxHash = null;
  let cssPath: string | null = path.replace('.tsx', '.css');
  let cssHash = null;

  // 处理复杂的schema结构
  let schema =
    typeof doc.schema === 'string' ? JSON.parse(doc.schema) : doc.schema;

  // 生成TSX代码并计算哈希
  doc.schema = schema;
  const tsxContent = await generateDocumentCode(doc, {
    path,
    generateRender: true,
    currentFrame: doc.frames?.includes('web') ? 'web' : 'app',
  });
  tsxHash = calculateHash(tsxContent);

  // 提取CSS内容并计算哈希
  let cssContent: string | null = null;
  if (schema.css) {
    cssContent = schema.css;
    cssHash = calculateHash(schema.css);
  } else {
    cssHash = null;
    cssPath = null;
  }

  return {
    path,
    cssPath,
    tsxHash,
    cssHash,
    cleanedSchema: schema,
    tsxContent, // 🆕 返回生成的代码
    cssContent, // 🆕 返回 CSS 内容
  };
}

/**
 * 计算ITypeEntity哈希值
 * @param typeItem ITypeEntity
 */
export async function calculateTypeEntityHashes(
  typeItem: ITypeEntity,
): Promise<{
  path: string;
  hash: string;
  size: number;
  typeItem: ITypeEntity;
}> {
  let path = getTypePath(typeItem);
  let hash = typeItem.hash;
  let size = typeItem.size || 0;

  // 生成代码并计算哈希
  try {
    const code = await getTypeFileCode(typeItem);
    if (!code) {
      console.log(typeItem);
    }
    hash = calculateHash(code);
    size = code?.length || 0;
  } catch (e) {
    console.error(e);
  }

  return {
    path,
    hash,
    size,
    typeItem,
  };
}

export async function getProjectFile(project: LcProject) {
  // 使用统一的字段常量
  const projectConfig: any = {};

  PROJECT_CONFIG_FIELDS.forEach(field => {
    if (project[field] !== undefined) {
      projectConfig[field] = project[field];
    }
  });

  const projectContent = JSON.stringify(projectConfig, undefined, 2);
  return projectContent;
}

/**
 * 计算项目HASH
 */
export async function calculateProjectHashes(project: LcProject): Promise<{
  path: string;
  hash: string;
  cssHash: string;
  cssPath: string;
  cleanedSchema: object;
  projectContent: string; // 🆕 返回项目配置内容
  cssContent: string | null; // 🆕 返回 CSS 内容
}> {
  const path = '/src/project.json';
  let hash = null;
  let cssHash = null;
  let cssPath = null;
  let cssContent: string | null = null;

  // 处理复杂的schema结构
  let schema =
    typeof project.schema === 'string'
      ? JSON.parse(project.schema)
      : project.schema;
  const projectContent = await getProjectFile(project);
  hash = calculateHash(projectContent);

  // 提取CSS内容并计算哈希
  if (schema?.css) {
    cssPath = '/src/app.css';
    cssContent = schema.css;
    cssHash = schema.css ? calculateHash(schema.css) : '';
  } else {
    cssHash = null;
    cssPath = null;
  }

  return {
    path,
    hash,
    cssPath,
    cssHash,
    cleanedSchema: schema,
    projectContent, // 🆕 返回项目配置内容
    cssContent, // 🆕 返回 CSS 内容
  };
}
